<!--
 * @Author: actor
 * @Date: 2023-11-09 09:40:37
 * @email: 395593455@qq.com
 * @LastEditors: actor
 * @LastEditTime: 2023-12-19 15:30:32
 * @FilePath: \i-hos-app\shared\emr\src\components\common\treeList.vue
 * @Description: 电子病历左侧树菜单栏
-->
<template>
  <div :class="['treeList', isCloseTreeList ? '' : 'close']">
    <!-- 
      展开收起按钮
     -->
    <div class="buttonIcon" @click="() => (isCloseTreeList = !isCloseTreeList)">
      <el-icon size="13" color="#79bbff">
        <ArrowLeftBold v-if="isCloseTreeList" />
        <ArrowRightBold v-else />
      </el-icon>
    </div>

    <!-- 
      菜单内容
     -->
    <div
      :style="{
        overflow: isCloseTreeList ? '' : 'hidden',
        width: '100%',
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
      }"
    >
      <!-- 
        菜单标题
       -->
      <div class="header">
        <div class="left">
          <el-icon size="17" color="#79bbff"><FolderOpened /></el-icon>{{ state.type }}
        </div>
        <div
          class="right"
          v-if="state.isHandletree"
          @click="
            (): void => {
              dialogvisible = !dialogvisible
            }
          "
        >
          <el-tooltip effect="dark" :content="`添加` + state.type + `分类`" placement="right">
            <el-icon size="18" color="#79bbff"><Plus /></el-icon>
          </el-tooltip>
        </div>
      </div>

      <!-- 
        菜单搜索查询
      -->
      <div class="tree-serach">
        <el-input
          placeholder="请输入查询分类的名称"
          suffix-icon="Search"
          clearable
          v-model="treeDataKeyword"
          @keyup.enter.prevent="filterTree()"
          @input="filterTree()"
        />
      </div>

      <!-- 
        菜单列表 
      -->
      <el-scrollbar>
        <el-tree v-if="treeData?.length" :data="treeData" :props="state.treeDataDefaultProps" accordion highlight-current>
          <!-- node-key="id"
          :current-node-key="1"
          :default-expanded-keys="[state.treeData[0].id]" -->
          <template #default="{ node, data }">
            <div class="el-tree-item">
              <span
                @click="handleNodeClick(node, data)"
                :class="['tree-item', node.isCurrent && !node.childNodes.length ? 'active' : '']"
              >
                <!--不管多少级， 只要有子集文件夹图标 -->
                <el-icon @click.stop="handleNodeClick(node, data)" size="15" v-if="node.childNodes.length"
                  ><FolderOpened
                /></el-icon>
                <!--不管多少级， 只要没有有子集文件图标 -->
                <el-icon @click.stop="handleNodeClick(node, data)" size="15" v-else><Document /></el-icon>
                {{ node.label }}
              </span>
              <span class="edit" v-if="state.isHandletree">
                <el-icon size="13" color="#a9a9a9" @click.stop="treeEdit(node, data)"><Edit /></el-icon>
                <el-icon size="13" color="#f56c6c" v-if="!data.childList" @click.stop="treeRemove(data)"><Delete /></el-icon>
              </span>
            </div>
          </template>
        </el-tree>
        <el-empty v-else description="暂无数据" :image-size="100">
          <el-button
            type="primary"
            v-if="state.isHandletree"
            @click="
              (): void => {
                dialogvisible = !dialogvisible
              }
            "
            >添加一个{{ state.type }}分类</el-button
          >
        </el-empty>
      </el-scrollbar>
    </div>
  </div>

  <!-- 
    添加编辑分类弹窗 
  -->
  <el-dialog
    v-if="state.isHandletree"
    v-model="dialogvisible"
    :title="`${'添加/编辑 _ ' + state.type + '分类'}`"
    width="400"
    align-center
    draggable
  >
    <el-form :model="sortForm" label-width="65px">
      <el-form-item label="父级分类">
        <v-combogrid
          :style="{ padding: 0 }"
          v-model="sortForm.parentId"
          v-model:inputlabel="sortForm.fatherName"
          :row-key="state.treeDataDefaultProps.id"
          :data="state.treeData"
          :fields="[state.treeDataDefaultProps.id, state.treeDataDefaultProps.label]"
          pid="parentId"
          height="300"
          width="300"
          :columns="[{ prop: state.treeDataDefaultProps.label, title: '名称' }]"
          :requestJSON-event="['change', 'enter']"
          :tree-props="{ children: 'childList' }"
        ></v-combogrid>
      </el-form-item>
      <el-form-item label="分类名称">
        <el-input clearable placeholder="请输入分类名称" v-model="sortForm.name" />
      </el-form-item>
      <el-form-item label="分类编码">
        <el-input clearable placeholder="请输入分类名称" v-model="sortForm.code" />
      </el-form-item>
      <el-form-item>
        <el-button
          @click="
            (): void => {
              dialogvisible = !dialogvisible
            }
          "
          >取消</el-button
        >
        <el-button type="primary" @click="commitAddSort">确定</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script setup lang="ts">
  import { ref, Ref, reactive, getCurrentInstance, watch } from 'vue'
  // 配置类型约束
  import { ISortForm, IPageShare } from '../../interface/pageShare'
  // 仓库数据以及解构store的配置数据
  import { useEmrPageShare } from '../../store/emrPageShare'
  const emrPageShare: IPageShare = useEmrPageShare()

  // 接收父组件值
  const props = defineProps({
    data: {
      type: Object,
      default: {},
    },
  })

  // 更新父组件方法
  let $emit = defineEmits<{
    (e: 'updateCategory', flag?: String): void
    (e: 'removeCategory', flag?: any): void
    (e: 'commitAddCategory', flag?: any): void
  }>()

  // 初始化数据
  let { proxy } = getCurrentInstance() as any,
    state: any = ref(props.data), // 父组件传的值
    isCloseTreeList: Ref<boolean> = ref(true), // 控制菜单栏展开和收缩
    dialogvisible: Ref<boolean> = ref(false), // 控制菜单栏分类新增或编辑弹层开启和关闭
    treeDataKeyword: Ref<string> = ref(''), // 树菜单搜索关键字
    sortForm: ISortForm = reactive({
      parentId: '',
      fatherName: '',
      id: '',
      name: '',
      code: '',
    }),
    treeData: Ref<any> = ref([])

  // 监听更新对应数据
  watch(
    (): any => [props.data, dialogvisible.value],
    (): any => {
      if (!!props.data) {
        state.value = props.data
        treeData.value = !!treeDataKeyword.value ? state.value.filterTreeData : state.value.treeData
      }
      if (!dialogvisible.value) {
        sortForm.parentId = ''
        sortForm.fatherName = ''
        sortForm.id = ''
        sortForm.name = ''
        sortForm.code = ''
      }
    },
    {
      immediate: true,
      deep: true,
    }
  )

  // 过滤查找树菜单
  const filterTree = (): void => $emit('updateCategory', treeDataKeyword.value)

  // 编辑回填数据分类
  const treeEdit = (node: any, data: any) => {
    // 回填数据
    dialogvisible.value = true
    // sortForm.type = 'edit'
    sortForm.id = data.emrKnowledgeBaseCategoryId
    sortForm.parentId = data.parentId
    sortForm.name = data.emrKnowledgeBaseCategoryName
    sortForm.fatherName = node.parent.data.emrKnowledgeBaseCategoryName
    sortForm.code = data.emrKnowledgeBaseCategoryCode
  }

  // 删除分类
  const treeRemove = (flag: any) => {
    let idArr: number[] = []
    idArr.push(flag.emrKnowledgeBaseCategoryId)
    // 查找删除的分类
    function getId(treeData: any, arr: number[]) {
      treeData.forEach((ele: any) => {
        arr.push(ele.emrKnowledgeBaseCategoryId)
        // 判断有子元素,并且子元素的长度大于0就再次调用自身
        if (ele.childList && ele.childList.length > 0) {
          getId(ele.childList, arr)
        }
      })
    }
    if (flag.childList && flag.childList.length > 0) {
      getId(flag.childList, idArr)
    }

    // 删除对应的知识库分类
    $emit('removeCategory', idArr)
  }

  // 添加或者编辑分类
  const commitAddSort = (): void => {
    let params: any = {
      parentId: sortForm.parentId,
      emrKnowledgeBaseCategoryId: sortForm.id,
      emrKnowledgeBaseCategoryName: sortForm.name,
      emrKnowledgeBaseCategoryCode: sortForm.code,
    }
    // 添加或者编辑知识库分类
    $emit('commitAddCategory', params)
    dialogvisible.value = false
  }

  //选择分类
  const handleNodeClick = (node: any, data: any) => {
    emrPageShare.$patch((state: IPageShare) => {
      state.activetreeList = data
    })
    if (!!data.deptName) {
      // 病历模板
      emrPageShare.fetchOrganizationTable(proxy, data)
    } else {
      // 知识库
      emrPageShare.fetchCategoryTable(proxy)
    }
  }
</script>

<style lang="scss" scoped>
  @keyframes zoom {
    from {
      transform: scale(1);
    }
    to {
      transform: scale(1.3);
    }
  }
  .treeList {
    width: 240px;
    height: 100%;
    background: #fff;
    border-radius: 4px;
    margin-right: 5px;
    position: relative;
    border: 1px solid #ebeef5;
    overflow: hidden;
    transition: all 0.2s;
    &.close {
      width: 0;
      border: none;
      overflow: initial;
      margin: 0;
      .buttonIcon {
        right: -12px;
        border-radius: 0 2px 2px 0;
      }
    }
    .buttonIcon {
      width: 12px;
      height: 50px;
      box-shadow: 0px 0px 3px #79bbff;
      position: absolute;
      top: 50%;
      right: 0;
      margin-top: -25px;
      cursor: pointer;
      align-items: center;
      display: flex;
      z-index: 99;
      background-color: #fff;
      border-radius: 2px 0 0 2px;
      .el-icon {
        animation: zoom 0.8s ease-in-out infinite alternate;
      }
    }

    .header {
      display: flex;
      justify-content: space-between;
      padding: 10px 5px;
      border-bottom: 1px solid #d8dce5;
      align-items: center;
      .left,
      .right {
        display: flex;
        align-items: center;
        font-size: 14px;
        color: #333;
      }
      .right {
        cursor: pointer;
      }
    }
    .el-tree-item {
      display: flex;
      justify-content: space-between;
      width: 100%;
      .edit {
        display: flex;
        align-items: center;
        .el-icon {
          margin-right: 5px;
        }
      }
    }
    el-scrollbar {
      width: 100%;
      height: 100%;
      overflow: auto;
      padding: 10px;
    }
    .tree-serach {
      width: calc(100% - 10px);
      margin: 8px auto;
    }
    :deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
      color: #79bbff;
    }
    :deep(.tree-item) {
      display: flex;
      align-items: center;
      font-size: var(--theme-font-size);
      flex: 1;
      .el-icon {
        margin-right: 3px;
      }
    }
  }
</style>
